﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using Windows8Accelerator.Core.Xaml.Commands;
using Windows8Accelerator.Core.Xaml.Helpers;

namespace Windows8Accelerator.Core.Xaml.Controls
{
    public sealed class SuperListView : Control, INotifyPropertyChanged
    {
        public SuperListView()
        {
            this.DefaultStyleKey = typeof(SuperListView);
            this.Loaded += SuperListView_Loaded;
            this.Unloaded += SuperListView_Unloaded;
            SelectedItems = new ObservableCollection<object>();
            SelectedItems.CollectionChanged += SelectedItems_CollectionChanged;
            this.SizeChanged += SuperListView_SizeChanged;
            GroupHeaderCommand = new DelegateCommand((o) => OnGroupHeaderCommand(o));
        }

        public DataTemplateSelector ItemTemplateSelector
        {
            get { return (DataTemplateSelector)GetValue(ItemTemplateSelectorProperty); }
            set { SetValue(ItemTemplateSelectorProperty, value); }
        }
        public static readonly DependencyProperty ItemTemplateSelectorProperty =
            DependencyProperty.Register("ItemTemplateSelector", typeof(DataTemplateSelector), typeof(SuperListView), new PropertyMetadata(null));

        void SuperListView_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            UpdateItemSize();
        }

        private void UpdateItemSize()
        {
            var itemWidth = new ItemLength("1/8");
            var itemHeight = new ItemLength("1/8");
            var groupMargin = SuperMargin.Zero;
            var panelMargin = SuperMargin.Zero;
            switch (AppHelper.Instance.ApplicationViewMode)
            {
                case ApplicationViewMode.Filled:
                    itemWidth = FilledItemWidth ?? FullScreenLandscapeItemWidth;
                    itemHeight = FilledItemHeight ?? FullScreenLandscapeItemHeight;
                    groupMargin = FilledGroupMargin ?? FullScreenLandscapeGroupMargin ?? groupMargin;
                    panelMargin = FilledPanelMargin ?? FullScreenLandscapePanelMargin ?? panelMargin;
                    break;
                case ApplicationViewMode.Landscape:
                    itemWidth = FullScreenLandscapeItemWidth;
                    itemHeight = FullScreenLandscapeItemHeight;
                    groupMargin = FullScreenLandscapeGroupMargin ?? groupMargin;
                    panelMargin = FullScreenLandscapePanelMargin ?? panelMargin;
                    break;
                case ApplicationViewMode.Portrait:
                    itemWidth = FullScreenPortraitItemWidth ?? FullScreenLandscapeItemWidth;
                    itemHeight = FullScreenPortraitItemHeight ?? FullScreenLandscapeItemHeight;
                    groupMargin = FullScreenPortraitGroupMargin ?? FullScreenLandscapeGroupMargin ?? groupMargin;
                    panelMargin = FullScreenPortraitPanelMargin ?? FullScreenLandscapePanelMargin ?? panelMargin;
                    break;
                case ApplicationViewMode.Snapped:
                    itemWidth = SnappedItemWidth ?? FullScreenLandscapeItemWidth;
                    itemHeight = SnappedItemHeight ?? FullScreenLandscapeItemHeight;
                    groupMargin = SnappedGroupMargin ?? FullScreenLandscapeGroupMargin ?? groupMargin;
                    panelMargin = SnappedPanelMargin ?? FullScreenLandscapePanelMargin ?? panelMargin;
                    break;
            }

            var actualGroupMargin = groupMargin.ToThickness(this.ActualWidth, this.ActualHeight);
            var actualPanelMargin = panelMargin.ToThickness(this.ActualWidth, this.ActualHeight);
            var internalHeight = ActualHeight - actualPanelMargin.Bottom - actualPanelMargin.Top;
            var internalWidth = ActualWidth - actualPanelMargin.Left - actualPanelMargin.Right;

            double actualItemWidth = 0; 
            double actualItemHeight = 0;
            if (itemWidth.UnitType == ItemLengthUnitTypes.ItemFraction)
            {
                actualItemHeight = itemHeight.ToDouble(internalHeight, actualItemWidth);
                actualItemWidth = itemWidth.ToDouble(internalWidth, actualItemHeight);
            }
            else
            {
                actualItemWidth = itemWidth.ToDouble(internalWidth, actualItemHeight);
                actualItemHeight = itemHeight.ToDouble(internalHeight, actualItemWidth);            
            }

            if (!(ItemsSource is ICollectionView) || ((ICollectionView)ItemsSource).Groups == null)
            {
                actualGroupMargin = actualPanelMargin;
            }

            if (ActualPanelMargin != actualPanelMargin)
                ActualPanelMargin = actualPanelMargin;
            if (ActualItemWidth != actualItemWidth)
                ActualItemWidth = actualItemWidth;
            if (ActualItemHeight != actualItemHeight)
                ActualItemHeight = actualItemHeight;
            if (ActualGroupMargin != actualGroupMargin)
                ActualGroupMargin = actualGroupMargin;
        }


        public SuperMargin FullScreenLandscapePanelMargin
        {
            get { return (SuperMargin)GetValue(FullScreenLandscapePanelMarginProperty); }
            set { SetValue(FullScreenLandscapePanelMarginProperty, value); }
        }
        public static readonly DependencyProperty FullScreenLandscapePanelMarginProperty =
            DependencyProperty.Register("FullScreenLandscapePanelMargin", typeof(SuperMargin), typeof(SuperListView), new PropertyMetadata(null));
        public string FullScreenLandscapePanelMarginString
        {
            get { return FullScreenLandscapePanelMargin.ToString(); }
            set { SetValue(FullScreenLandscapePanelMarginProperty, new SuperMargin(value)); }
        }


        public SuperMargin FullScreenPortraitPanelMargin
        {
            get { return (SuperMargin)GetValue(FullScreenPortraitPanelMarginProperty); }
            set { SetValue(FullScreenPortraitPanelMarginProperty, value); }
        }
        public static readonly DependencyProperty FullScreenPortraitPanelMarginProperty =
            DependencyProperty.Register("FullScreenPortraitPanelMargin", typeof(SuperMargin), typeof(SuperListView), new PropertyMetadata(null));
        public string FullScreenPortraitPanelMarginString
        {
            get { return FullScreenPortraitPanelMargin.ToString(); }
            set { SetValue(FullScreenPortraitPanelMarginProperty, new SuperMargin(value)); }
        }

        public SuperMargin SnappedPanelMargin
        {
            get { return (SuperMargin)GetValue(SnappedPanelMarginProperty); }
            set { SetValue(SnappedPanelMarginProperty, value); }
        }
        public static readonly DependencyProperty SnappedPanelMarginProperty =
            DependencyProperty.Register("SnappedPanelMargin", typeof(SuperMargin), typeof(SuperListView), new PropertyMetadata(null));
        public string SnappedPanelMarginString
        {
            get { return SnappedPanelMargin.ToString(); }
            set { SetValue(SnappedPanelMarginProperty, new SuperMargin(value)); }
        }

        public SuperMargin FilledPanelMargin
        {
            get { return (SuperMargin)GetValue(FilledPanelMarginProperty); }
            set { SetValue(FilledPanelMarginProperty, value); }
        }
        public static readonly DependencyProperty FilledPanelMarginProperty =
            DependencyProperty.Register("FilledPanelMargin", typeof(SuperMargin), typeof(SuperListView), new PropertyMetadata(null));
        public string FilledPanelMarginString
        {
            get { return FilledPanelMargin.ToString(); }
            set { SetValue(FilledPanelMarginProperty, new SuperMargin(value)); }
        }

        public Thickness ActualPanelMargin
        {
            get { return (Thickness)GetValue(ActualPanelMarginProperty); }
            set { SetValue(ActualPanelMarginProperty, value); }
        }
        public static readonly DependencyProperty ActualPanelMarginProperty =
            DependencyProperty.Register("ActualPanelMargin", typeof(Thickness), typeof(SuperListView), new PropertyMetadata(new Thickness(0)));

        public ListViewSelectionMode SelectionMode
        {
            get { return (ListViewSelectionMode)GetValue(SelectionModeProperty); }
            set { SetValue(SelectionModeProperty, value); }
        }
        public static readonly DependencyProperty SelectionModeProperty =
            DependencyProperty.Register("SelectionMode", typeof(ListViewSelectionMode), typeof(SuperListView), new PropertyMetadata(ListViewSelectionMode.Single));

        void SelectedItems_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
            if (_ListViewBaseContentControl != null && !_SelfUpdating)
            {
                _SelfUpdating = true;
                if (SelectionMode == ListViewSelectionMode.Extended || SelectionMode == ListViewSelectionMode.Multiple)
                {
                    if (e.NewItems != null)
                        foreach (var item in e.NewItems)
                            _ListViewBaseContentControl.SelectedItems.Add(item);
                    if (e.OldItems != null)
                        foreach (var item in e.OldItems)
                            _ListViewBaseContentControl.SelectedItems.Remove(item);
                    if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Reset)
                    {
                        _ListViewBaseContentControl.SelectedItems.Clear();
                        foreach (var item in SelectedItems)
                            _ListViewBaseContentControl.SelectedItems.Add(item);
                    }
                }
                _SelfUpdating = false;
            }
        }

        public object SelectedItem
        {
            get { return (object)GetValue(SelectedItemProperty); }
            set
            {
                SetValue(SelectedItemProperty, value);
                if (_ListViewBaseContentControl != null && !_SelfUpdating)
                {
                    _SelfUpdating = true;
                    _ListViewBaseContentControl.SelectedItem = value;
                    if (SelectionMode == ListViewSelectionMode.Extended || SelectionMode == ListViewSelectionMode.Multiple)
                    {
                        if (value != null && !SelectedItems.Contains(value))
                            SelectedItems.Add(value);
                    }
                    _SelfUpdating = false;
                }
            }
        }
        public static readonly DependencyProperty SelectedItemProperty =
            DependencyProperty.Register("SelectedItem", typeof(object), typeof(SuperListView), new PropertyMetadata(null));


        public ObservableCollection<object> SelectedItems { get; private set; }

        public Func<object, Tuple<int, int>, Tuple<int,int>> ItemColumnAndRowSpanSelector { get; set; }

        public Tuple<int, int> GetItemColumnAndRowSpanSelector(object item)
        {
            var defaultColumnAndRowSpan = new Tuple<int, int>(1, 1);
            if (ItemColumnAndRowSpanSelector != null)
                return ItemColumnAndRowSpanSelector(item, defaultColumnAndRowSpan);
            return defaultColumnAndRowSpan;
        }

        public string PageDestinationOnItemClick
        {
            get { return (string)GetValue(PageDestinationOnItemClickProperty); }
            set { SetValue(PageDestinationOnItemClickProperty, value); }
        }
        public static readonly DependencyProperty PageDestinationOnItemClickProperty =
            DependencyProperty.Register("PageDestinationOnItemClick", typeof(string), typeof(SuperListView), new PropertyMetadata(null));
        
        public Type PageDestinationTypeOnItemClick
        {
            get { return (Type)GetValue(PageDestinationTypeOnItemClickProperty); }
            set { SetValue(PageDestinationTypeOnItemClickProperty, value); }
        }
        public static readonly DependencyProperty PageDestinationTypeOnItemClickProperty =
            DependencyProperty.Register("PageDestinationTypeOnItemClick", typeof(Type), typeof(SuperListView), new PropertyMetadata(null));

        public Type PageDestinationTypeOnGroupHeaderClick
        {
            get { return (Type)GetValue(PageDestinationTypeOnGroupHeaderClickProperty); }
            set { SetValue(PageDestinationTypeOnGroupHeaderClickProperty, value); }
        }
        public static readonly DependencyProperty PageDestinationTypeOnGroupHeaderClickProperty =
            DependencyProperty.Register("PageDestinationTypeOnGroupHeaderClick", typeof(Type), typeof(SuperListView), new PropertyMetadata(null));

        void SuperListView_Loaded(object sender, RoutedEventArgs e)
        {
            AppHelper.CurrentPage.OrientationChanged += CurrentPage_OrientationChanged;
        }

        void SuperListView_Unloaded(object sender, RoutedEventArgs e)
        {
            AppHelper.CurrentPage.OrientationChanged -= CurrentPage_OrientationChanged;
        }

        private ApplicationViewMode? PreviousApplicationViewState;

        void CurrentPage_OrientationChanged(object sender, Microsoft.Phone.Controls.OrientationChangedEventArgs e)
        {
            if (PreviousApplicationViewState != AppHelperBase.Instance.ApplicationViewMode)
            {
                PreviousApplicationViewState = AppHelperBase.Instance.ApplicationViewMode;
                UpdateViewStyle();
                UpdateItemSize();
            }
        }

        private void UpdateViewStyle()
        {
            Style viewStyle = null;
            DataTemplate itemTemplate = null;
            DataTemplate groupHeaderTemplate = null;
            ItemsPanelTemplate itemsPanelTemplate = null;
            ItemsPanelTemplate groupedItemsPanelTemplate = null;
            switch (AppHelperBase.Instance.ApplicationViewMode)
            {
                case ApplicationViewMode.Filled:
                    viewStyle = FilledViewStyle ?? FullScreenLandscapeViewStyle;
                    itemTemplate = FilledItemTemplate ?? FullScreenLandscapeItemTemplate;
                    groupHeaderTemplate = FilledGroupHeaderTemplate ?? FullScreenLandscapeGroupHeaderTemplate;
                    itemsPanelTemplate = FullScreenLandscapeItemsPanelTemplate;
                    groupedItemsPanelTemplate = FullScreenLandscapeGroupedItemsPanelTemplate;
                    break;
                case ApplicationViewMode.Landscape:
                    viewStyle = FullScreenLandscapeViewStyle;
                    itemTemplate = FullScreenLandscapeItemTemplate;
                    groupHeaderTemplate = FullScreenLandscapeGroupHeaderTemplate;
                    itemsPanelTemplate = FullScreenLandscapeItemsPanelTemplate;
                    groupedItemsPanelTemplate = FullScreenLandscapeGroupedItemsPanelTemplate;
                    break;
                case ApplicationViewMode.Portrait:
                    viewStyle = FullScreenPortraitViewStyle ?? FullScreenLandscapeViewStyle;
                    itemTemplate = FullScreenPortraitItemTemplate ?? FullScreenLandscapeItemTemplate;
                    groupHeaderTemplate = FullScreenPortraitGroupHeaderTemplate ?? FullScreenLandscapeGroupHeaderTemplate;
                    itemsPanelTemplate = FullScreenLandscapeItemsPanelTemplate;
                    groupedItemsPanelTemplate = FullScreenLandscapeGroupedItemsPanelTemplate;
                    break;
                case ApplicationViewMode.Snapped:
                    viewStyle = SnappedViewStyle ?? FullScreenLandscapeViewStyle;
                    itemTemplate = SnappedItemTemplate ?? FullScreenLandscapeItemTemplate;
                    groupHeaderTemplate = SnappedGroupHeaderTemplate ?? FullScreenLandscapeGroupHeaderTemplate;
                    itemsPanelTemplate = SnappedItemsPanelTemplate ?? FullScreenLandscapeItemsPanelTemplate;
                    groupedItemsPanelTemplate = SnappedGroupedItemsPanelTemplate ?? FullScreenLandscapeGroupedItemsPanelTemplate;
                    break;
            }

            if (ItemsSource is ICollectionView && ((ICollectionView)ItemsSource).Groups != null)
            {
                var temp = itemsPanelTemplate;
                itemsPanelTemplate = groupedItemsPanelTemplate;
                groupedItemsPanelTemplate = temp;
            }
                

            if (viewStyle != DynamicViewStyle)
                DynamicViewStyle = viewStyle;
            if (itemTemplate != DynamicItemTemplate)
                DynamicItemTemplate = itemTemplate;
            if (groupHeaderTemplate != DynamicGroupHeaderTemplate)
                DynamicGroupHeaderTemplate = groupHeaderTemplate;
            if (itemsPanelTemplate != DynamicItemsPanelTemplate)
                DynamicItemsPanelTemplate = itemsPanelTemplate;
            if (groupedItemsPanelTemplate != DynamicGroupedItemsPanelTemplate)
                DynamicGroupedItemsPanelTemplate = groupedItemsPanelTemplate;
        }

        public object ItemsSource
        {
            get { return (object)GetValue(ItemsSourceProperty); }
            set { SetValue(ItemsSourceProperty, value); }
        }
        public static readonly DependencyProperty ItemsSourceProperty =
            DependencyProperty.Register("ItemsSource", typeof(object), typeof(SuperListView), new PropertyMetadata(null));

        #region ViewStyleProperties

        public Style SnappedViewStyle
        {
            get { return (Style)GetValue(SnappedViewStyleProperty); }
            set { SetValue(SnappedViewStyleProperty, value); }
        }
        public static readonly DependencyProperty SnappedViewStyleProperty =
            DependencyProperty.Register("SnappedViewStyle", typeof(Style), typeof(SuperListView), new PropertyMetadata(null));

        public Style FullScreenLandscapeViewStyle
        {
            get { return (Style)GetValue(FullScreenLandscapeViewStyleProperty); }
            set { SetValue(FullScreenLandscapeViewStyleProperty, value); }
        }
        public static readonly DependencyProperty FullScreenLandscapeViewStyleProperty =
            DependencyProperty.Register("FullScreenLandscapeViewStyle", typeof(Style), typeof(SuperListView), new PropertyMetadata(null));

        public Style FilledViewStyle
        {
            get { return (Style)GetValue(FilledViewStyleProperty); }
            set { SetValue(FilledViewStyleProperty, value); }
        }
        public static readonly DependencyProperty FilledViewStyleProperty =
            DependencyProperty.Register("FilledViewStyle", typeof(Style), typeof(SuperListView), new PropertyMetadata(null));

        public Style FullScreenPortraitViewStyle
        {
            get { return (Style)GetValue(FullScreenPortraitViewStyleProperty); }
            set { SetValue(FullScreenPortraitViewStyleProperty, value); }
        }
        public static readonly DependencyProperty FullScreenPortraitViewStyleProperty =
            DependencyProperty.Register("FullScreenPortraitViewStyle", typeof(Style), typeof(SuperListView), new PropertyMetadata(null));

        public Style DynamicViewStyle
        {
            get { return (Style)GetValue(DynamicViewStyleProperty); }
            private set { SetValue(DynamicViewStyleProperty, value); }
        }
        public static readonly DependencyProperty DynamicViewStyleProperty =
            DependencyProperty.Register("DynamicViewStyle", typeof(Style), typeof(SuperListView), new PropertyMetadata(null));
        
        #endregion ViewStyleProperties


        #region ItemTemplateProperties

        public DataTemplate SnappedItemTemplate
        {
            get { return (DataTemplate)GetValue(SnappedItemTemplateProperty); }
            set { SetValue(SnappedItemTemplateProperty, value); }
        }
        public static readonly DependencyProperty SnappedItemTemplateProperty =
            DependencyProperty.Register("SnappedItemTemplate", typeof(DataTemplate), typeof(SuperListView), new PropertyMetadata(null));

        public DataTemplate FilledItemTemplate
        {
            get { return (DataTemplate)GetValue(FilledItemTemplateProperty); }
            set { SetValue(FilledItemTemplateProperty, value); }
        }
        public static readonly DependencyProperty FilledItemTemplateProperty =
            DependencyProperty.Register("FilledItemTemplate", typeof(DataTemplate), typeof(SuperListView), new PropertyMetadata(null));

        public DataTemplate FullScreenLandscapeItemTemplate
        {
            get { return (DataTemplate)GetValue(FullScreenLandscapeItemTemplateProperty); }
            set { SetValue(FullScreenLandscapeItemTemplateProperty, value); }
        }
        public static readonly DependencyProperty FullScreenLandscapeItemTemplateProperty =
            DependencyProperty.Register("FullScreenLandscapeItemTemplate", typeof(DataTemplate), typeof(SuperListView), new PropertyMetadata(null));

        public DataTemplate FullScreenPortraitItemTemplate
        {
            get { return (DataTemplate)GetValue(FullScreenPortraitItemTemplateProperty); }
            set { SetValue(FullScreenPortraitItemTemplateProperty, value); }
        }
        public static readonly DependencyProperty FullScreenPortraitItemTemplateProperty =
            DependencyProperty.Register("FullScreenPortraitItemTemplate", typeof(DataTemplate), typeof(SuperListView), new PropertyMetadata(null));

        public DataTemplate DynamicItemTemplate
        {
            get { return (DataTemplate)GetValue(DynamicItemTemplateProperty); }
            private set { SetValue(DynamicItemTemplateProperty, value); }
        }
        public static readonly DependencyProperty DynamicItemTemplateProperty =
            DependencyProperty.Register("DynamicItemTemplate", typeof(DataTemplate), typeof(SuperListView), new PropertyMetadata(null));

        #endregion ItemTemplateProperties

        #region GroupHeaderTemplateProperties

        public DataTemplate SnappedGroupHeaderTemplate
        {
            get { return (DataTemplate)GetValue(SnappedGroupHeaderTemplateProperty); }
            set { SetValue(SnappedGroupHeaderTemplateProperty, value); }
        }
        public static readonly DependencyProperty SnappedGroupHeaderTemplateProperty =
            DependencyProperty.Register("SnappedGroupHeaderTemplate", typeof(DataTemplate), typeof(SuperListView), new PropertyMetadata(null));

        public DataTemplate FilledGroupHeaderTemplate
        {
            get { return (DataTemplate)GetValue(FilledGroupHeaderTemplateProperty); }
            set { SetValue(FilledGroupHeaderTemplateProperty, value); }
        }
        public static readonly DependencyProperty FilledGroupHeaderTemplateProperty =
            DependencyProperty.Register("FilledGroupHeaderTemplate", typeof(DataTemplate), typeof(SuperListView), new PropertyMetadata(null));

        public DataTemplate FullScreenLandscapeGroupHeaderTemplate
        {
            get { return (DataTemplate)GetValue(FullScreenLandscapeGroupHeaderTemplateProperty); }
            set { SetValue(FullScreenLandscapeGroupHeaderTemplateProperty, value); }
        }
        public static readonly DependencyProperty FullScreenLandscapeGroupHeaderTemplateProperty =
            DependencyProperty.Register("FullScreenLandscapeGroupHeaderTemplate", typeof(DataTemplate), typeof(SuperListView), new PropertyMetadata(null));

        public DataTemplate FullScreenPortraitGroupHeaderTemplate
        {
            get { return (DataTemplate)GetValue(FullScreenPortraitGroupHeaderTemplateProperty); }
            set { SetValue(FullScreenPortraitGroupHeaderTemplateProperty, value); }
        }
        public static readonly DependencyProperty FullScreenPortraitGroupHeaderTemplateProperty =
            DependencyProperty.Register("FullScreenPortraitGroupHeaderTemplate", typeof(DataTemplate), typeof(SuperListView), new PropertyMetadata(null));

        public DataTemplate DynamicGroupHeaderTemplate
        {
            get { return (DataTemplate)GetValue(DynamicGroupHeaderTemplateProperty); }
            private set { SetValue(DynamicGroupHeaderTemplateProperty, value); }
        }
        public static readonly DependencyProperty DynamicGroupHeaderTemplateProperty =
            DependencyProperty.Register("DynamicGroupHeaderTemplate", typeof(DataTemplate), typeof(SuperListView), new PropertyMetadata(null));

        #endregion GroupHeaderTemplateProperties


        private ListViewBaseContentControl _ListViewBaseContentControl;

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();

            _ListViewBaseContentControl = GetTemplateChild("ListViewBaseContentControl") as ListViewBaseContentControl;
            if (_ListViewBaseContentControl != null)
            {
                _SelfUpdating = true;
                _ListViewBaseContentControl.SelectedItem = SelectedItem;
                if (SelectionMode == ListViewSelectionMode.Extended || SelectionMode == ListViewSelectionMode.Multiple)
                {
                    if (SelectedItem != null && !_ListViewBaseContentControl.SelectedItems.Contains(SelectedItem))
                        _ListViewBaseContentControl.SelectedItems.Add(SelectedItem);
                    foreach (var item in SelectedItems.Where((o) => !_ListViewBaseContentControl.SelectedItems.Contains(o)))
                        _ListViewBaseContentControl.SelectedItems.Add(item);
                    foreach (var item in _ListViewBaseContentControl.SelectedItems.Where((o) => !SelectedItems.Contains(o) && o != SelectedItem))
                        _ListViewBaseContentControl.SelectedItems.Remove(item);
                }
                _ListViewBaseContentControl.SelectionChanged += _ListViewBaseContentControl_SelectionChanged;
                _ListViewBaseContentControl.ItemClick += _ListViewBaseContentControl_ItemClick;
                _SelfUpdating = false;

            }
            UpdateViewStyle();
        }

        public ICommand GroupHeaderCommand
        {
            get { return (ICommand)GetValue(GroupHeaderCommandProperty); }
            private set { SetValue(GroupHeaderCommandProperty, value); }
        }
        public static readonly DependencyProperty GroupHeaderCommandProperty =
            DependencyProperty.Register("GroupHeaderCommand", typeof(ICommand), typeof(SuperListView), new PropertyMetadata(null));

        void _ListViewBaseContentControl_ItemClick(object sender, ItemClickEventArgs e)
        {
            if (PageDestinationTypeOnItemClick != null)
            {
                AppHelperBase.Instance.NavigateAsync(PageDestinationTypeOnItemClick, e.ClickedItem);
            }
            if (ItemClick != null)
                ItemClick(sender, new SuperItemClickEventArgs() { Item = e.ClickedItem });
        }

        void OnGroupHeaderCommand(object parameter)
        {
            if (PageDestinationTypeOnGroupHeaderClick != null)
            {
                AppHelperBase.Instance.NavigateAsync(PageDestinationTypeOnGroupHeaderClick, parameter);
            }
            if (GroupHeaderClick != null)
                GroupHeaderClick(this, new SuperItemClickEventArgs() { Item = parameter });
        }

        public event EventHandler<SuperItemClickEventArgs> GroupHeaderClick;
        public event EventHandler<SuperItemClickEventArgs> ItemClick;

        private bool _SelfUpdating;

        public ItemLength FullScreenLandscapeItemWidth
        {
            get { return (ItemLength)GetValue(FullScreenLandscapeItemWidthProperty); }
            set 
            { 
                SetValue(FullScreenLandscapeItemWidthProperty, value);
                UpdateItemSize();
            }
        }
        public static readonly DependencyProperty FullScreenLandscapeItemWidthProperty =
            DependencyProperty.Register("FullScreenLandscapeItemWidth", typeof(ItemLength), typeof(SuperListView), new PropertyMetadata(new ItemLength("1/8")));

        public double ActualItemWidth
        {
            get { return (double)GetValue(ActualItemWidthProperty); }
            private set { SetValue(ActualItemWidthProperty, value); }
        }
        public static readonly DependencyProperty ActualItemWidthProperty =
            DependencyProperty.Register("ActualItemWidth", typeof(double), typeof(SuperListView), new PropertyMetadata(default(double)));

        public ItemLength FullScreenLandscapeItemHeight
        {
            get { return (ItemLength)GetValue(FullScreenLandscapeItemHeightProperty); }
            set
            {
                SetValue(FullScreenLandscapeItemHeightProperty, value);
                UpdateItemSize();
            }
        }
        public static readonly DependencyProperty FullScreenLandscapeItemHeightProperty =
            DependencyProperty.Register("FullScreenLandscapeItemHeight", typeof(ItemLength), typeof(SuperListView), new PropertyMetadata(new ItemLength("1/8")));

        public string FullScreenLandscapeItemWidthString
        {
            get { return FullScreenLandscapeItemWidth.ToString(); }
            set { SetValue(FullScreenLandscapeItemWidthStringProperty, value); }
        }
        public static readonly DependencyProperty FullScreenLandscapeItemWidthStringProperty =
            DependencyProperty.Register("FullScreenLandscapeItemWidthString", typeof(string), typeof(SuperListView), new PropertyMetadata(null, FullScreenLandscapeItemWidthStringPropertyChanged));

        private static void FullScreenLandscapeItemWidthStringPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((SuperListView)d).FullScreenLandscapeItemWidth = new ItemLength((string)e.NewValue);
        }

        public string FullScreenLandscapeItemHeightString
        {
            get { return FullScreenLandscapeItemHeight.ToString(); }
            set { SetValue(FullScreenLandscapeItemHeightStringProperty, value); }
        }
        public static readonly DependencyProperty FullScreenLandscapeItemHeightStringProperty =
            DependencyProperty.Register("FullScreenLandscapeItemHeightString", typeof(string), typeof(SuperListView), new PropertyMetadata(null, FullScreenLandscapeItemHeightStringPropertyChanged));

        private static void FullScreenLandscapeItemHeightStringPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((SuperListView)d).FullScreenLandscapeItemHeight = new ItemLength((string)e.NewValue);
        }

        
        public double ActualItemHeight
        {
            get { return (double)GetValue(ActualItemHeightProperty); }
            private set { SetValue(ActualItemHeightProperty, value); }
        }
        public static readonly DependencyProperty ActualItemHeightProperty =
            DependencyProperty.Register("ActualItemHeight", typeof(double), typeof(SuperListView), new PropertyMetadata(default(double)));

        public SuperMargin FullScreenLandscapeGroupMargin
        {
            get { return (SuperMargin)GetValue(FullScreenLandscapeGroupMarginProperty); }
            set
            {
                SetValue(FullScreenLandscapeGroupMarginProperty, value);
                UpdateItemSize();
            }
        }
        public static readonly DependencyProperty FullScreenLandscapeGroupMarginProperty =
            DependencyProperty.Register("FullScreenLandscapeGroupMargin", typeof(SuperMargin), typeof(SuperListView), new PropertyMetadata(null));
        public string FullScreenLandscapeGroupMarginString
        {
            get { return FullScreenLandscapeGroupMargin.ToString(); }
            set { SetValue(FullScreenLandscapeGroupMarginProperty, new SuperMargin(value)); }
        }
        public Thickness ActualGroupMargin
        {
            get { return (Thickness)GetValue(ActualGroupMarginProperty); }
            private set { SetValue(ActualGroupMarginProperty, value); }
        }
        public static readonly DependencyProperty ActualGroupMarginProperty =
            DependencyProperty.Register("ActualGroupMargin", typeof(Thickness), typeof(SuperListView), new PropertyMetadata(new Thickness()));

        public ItemLength SnappedItemWidth
        {
            get { return (ItemLength)GetValue(SnappedItemWidthProperty); }
            set
            {
                SetValue(SnappedItemWidthProperty, value);
                UpdateItemSize();
            }
        }
        public static readonly DependencyProperty SnappedItemWidthProperty =
            DependencyProperty.Register("SnappedItemWidth", typeof(ItemLength), typeof(SuperListView), new PropertyMetadata(new ItemLength("1/1")));

        public ItemLength SnappedItemHeight
        {
            get { return (ItemLength)GetValue(SnappedItemHeightProperty); }
            set
            {
                SetValue(SnappedItemHeightProperty, value);
                UpdateItemSize();
            }
        }
        public static readonly DependencyProperty SnappedItemHeightProperty =
            DependencyProperty.Register("SnappedItemHeight", typeof(ItemLength), typeof(SuperListView), new PropertyMetadata(new ItemLength("1/20")));

        public string SnappedItemWidthString
        {
            get { return SnappedItemWidth.ToString(); }
            set { SetValue(SnappedItemWidthStringProperty, value); }
        }
        public static readonly DependencyProperty SnappedItemWidthStringProperty =
            DependencyProperty.Register("SnappedItemWidthString", typeof(string), typeof(SuperListView), new PropertyMetadata(null, SnappedItemWidthStringPropertyChanged));

        private static void SnappedItemWidthStringPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((SuperListView)d).SnappedItemWidth = new ItemLength((string)e.NewValue);
        }

        public string SnappedItemHeightString
        {
            get { return SnappedItemHeight.ToString(); }
            set { SetValue(SnappedItemHeightStringProperty, value); }
        }
        public static readonly DependencyProperty SnappedItemHeightStringProperty =
            DependencyProperty.Register("SnappedItemHeightString", typeof(string), typeof(SuperListView), new PropertyMetadata(null, SnappedItemHeightStringPropertyChanged));

        private static void SnappedItemHeightStringPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((SuperListView)d).SnappedItemHeight = new ItemLength((string)e.NewValue);
        }


        public SuperMargin SnappedGroupMargin
        {
            get { return (SuperMargin)GetValue(SnappedGroupMarginProperty); }
            set
            {
                SetValue(SnappedGroupMarginProperty, value);
                UpdateItemSize();
            }
        }
        public static readonly DependencyProperty SnappedGroupMarginProperty =
            DependencyProperty.Register("SnappedGroupMargin", typeof(SuperMargin), typeof(SuperListView), new PropertyMetadata(null));
        public string SnappedGroupMarginString
        {
            get { return SnappedGroupMargin.ToString(); }
            set { SetValue(SnappedGroupMarginProperty, new SuperMargin(value)); }
        }

        public ItemLength FullScreenPortraitItemWidth
        {
            get { return (ItemLength)GetValue(FullScreenPortraitItemWidthProperty); }
            set
            {
                SetValue(FullScreenPortraitItemWidthProperty, value);
                UpdateItemSize();
            }
        }
        public static readonly DependencyProperty FullScreenPortraitItemWidthProperty =
            DependencyProperty.Register("FullScreenPortraitItemWidth", typeof(ItemLength), typeof(SuperListView), new PropertyMetadata(default(ItemLength)));
        public string FullScreenPortraitItemWidthString
        {
            get { return FullScreenPortraitItemWidth.ToString(); }
            set { SetValue(FullScreenPortraitItemWidthProperty, new ItemLength(value)); }
        }

        public ItemLength FullScreenPortraitItemHeight
        {
            get { return (ItemLength)GetValue(FullScreenPortraitItemHeightProperty); }
            set
            {
                SetValue(FullScreenPortraitItemHeightProperty, value);
                UpdateItemSize();
            }
        }
        public static readonly DependencyProperty FullScreenPortraitItemHeightProperty =
            DependencyProperty.Register("FullScreenPortraitItemHeight", typeof(ItemLength), typeof(SuperListView), new PropertyMetadata(default(ItemLength)));
        public string FullScreenPortraitItemHeightString
        {
            get { return FullScreenPortraitItemHeight.ToString(); }
            set { SetValue(FullScreenPortraitItemHeightProperty, new ItemLength(value)); }
        }

        public SuperMargin FullScreenPortraitGroupMargin
        {
            get { return (SuperMargin)GetValue(FullScreenPortraitGroupMarginProperty); }
            set
            {
                SetValue(FullScreenPortraitGroupMarginProperty, value);
                UpdateItemSize();
            }
        }
        public static readonly DependencyProperty FullScreenPortraitGroupMarginProperty =
            DependencyProperty.Register("FullScreenPortraitGroupMargin", typeof(SuperMargin), typeof(SuperListView), new PropertyMetadata(null));
        public string FullScreenPortraitGroupMarginString
        {
            get { return FullScreenPortraitGroupMargin.ToString(); }
            set { SetValue(FullScreenPortraitGroupMarginProperty, new SuperMargin(value)); }
        }

        public ItemLength FilledItemWidth
        {
            get { return (ItemLength)GetValue(FilledItemWidthProperty); }
            set
            {
                SetValue(FilledItemWidthProperty, value);
                UpdateItemSize();
            }
        }
        public static readonly DependencyProperty FilledItemWidthProperty =
            DependencyProperty.Register("FilledItemWidth", typeof(ItemLength), typeof(SuperListView), new PropertyMetadata(null));
        public string FilledItemWidthString
        {
            get { return FilledItemWidth.ToString(); }
            set { SetValue(FilledItemWidthProperty, new ItemLength(value)); }
        }

        public ItemLength FilledItemHeight
        {
            get { return (ItemLength)GetValue(FilledItemHeightProperty); }
            set
            {
                SetValue(FilledItemHeightProperty, value);
                UpdateItemSize();
            }
        }
        public static readonly DependencyProperty FilledItemHeightProperty =
            DependencyProperty.Register("FilledItemHeight", typeof(ItemLength), typeof(SuperListView), new PropertyMetadata(null));
        public string FilledItemHeightString
        {
            get { return FilledItemHeight.ToString(); }
            set { SetValue(FilledItemHeightProperty, new ItemLength(value)); }
        }

        public SuperMargin FilledGroupMargin
        {
            get { return (SuperMargin)GetValue(FilledGroupMarginProperty); }
            set
            {
                SetValue(FilledGroupMarginProperty, value);
                UpdateItemSize();
            }
        }
        public static readonly DependencyProperty FilledGroupMarginProperty =
            DependencyProperty.Register("FilledGroupMargin", typeof(SuperMargin), typeof(SuperListView), new PropertyMetadata(null));
        public string FilledGroupMarginString
        {
            get { return FilledGroupMargin.ToString(); }
            set { SetValue(FilledGroupMarginProperty, new SuperMargin(value)); }
        }

        void _ListViewBaseContentControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (!_SelfUpdating)
            {
                _SelfUpdating = true;
                if (e.AddedItems.Count > 0)
                    SelectedItem = e.AddedItems[0];
                else
                    SelectedItem = null;
                if (SelectionMode == ListViewSelectionMode.Extended || SelectionMode == ListViewSelectionMode.Multiple)
                {
                    foreach (var item in e.AddedItems)
                        SelectedItems.Add(e);
                    foreach (var item in e.RemovedItems)
                        SelectedItems.Remove(e);
                }

                //if (SemanticZoomOwner != null && !IsZoomedInView)
                //{
                //    SemanticZoomOwner.ToggleActiveView();
                //    SemanticZoomOwner.ZoomedInView.MakeVisible(new SemanticZoomLocation() { Item = SelectedItem });
                //    SelectedItems.Clear();
                //    SelectedItem = null;
                //    _ListViewBaseContentControl.SelectedItems.Clear();
                //    _ListViewBaseContentControl.SelectedItem = null;
                //}

                _SelfUpdating = false;
            }

            if (SelectionChanged != null)
                SelectionChanged(sender, e);
        }

        public event SelectionChangedEventHandler SelectionChanged;

        public void InitializeViewChange()
        {
        }

        public ItemsPanelTemplate DynamicItemsPanelTemplate
        {
            get { return (ItemsPanelTemplate)GetValue(DynamicItemsPanelTemplateProperty); }
            set { SetValue(DynamicItemsPanelTemplateProperty, value); }
        }
        public static readonly DependencyProperty DynamicItemsPanelTemplateProperty =
            DependencyProperty.Register("DynamicItemsPanelTemplate", typeof(ItemsPanelTemplate), typeof(SuperListView), new PropertyMetadata(null));

        public ItemsPanelTemplate DynamicGroupedItemsPanelTemplate
        {
            get { return (ItemsPanelTemplate)GetValue(DynamicGroupedItemsPanelTemplateProperty); }
            set { SetValue(DynamicGroupedItemsPanelTemplateProperty, value); }
        }
        public static readonly DependencyProperty DynamicGroupedItemsPanelTemplateProperty =
            DependencyProperty.Register("DynamicGroupedItemsPanelTemplate", typeof(ItemsPanelTemplate), typeof(SuperListView), new PropertyMetadata(null, PropertyChangedCallback));

        private static void PropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e) 
        { 
            var superListView = (SuperListView)d;
            superListView.OnPropertyChanged(e.Property);
        }

        private void OnPropertyChanged(DependencyProperty dependencyProperty)
        {
            var propertyName = "";
            if (dependencyProperty == DynamicGroupedItemsPanelTemplateProperty)
                propertyName = "DynamicGroupedItemsPanelTemplate";

            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }


        public ItemsPanelTemplate FullScreenLandscapeGroupedItemsPanelTemplate
        {
            get { return (ItemsPanelTemplate)GetValue(FullScreenLandscapeGroupedItemsPanelTemplateProperty); }
            set { SetValue(FullScreenLandscapeGroupedItemsPanelTemplateProperty, value); }
        }
        public static readonly DependencyProperty FullScreenLandscapeGroupedItemsPanelTemplateProperty =
            DependencyProperty.Register("FullScreenLandscapeGroupedItemsPanelTemplate", typeof(ItemsPanelTemplate), typeof(SuperListView), new PropertyMetadata(null));

        public ItemsPanelTemplate FullScreenLandscapeItemsPanelTemplate
        {
            get { return (ItemsPanelTemplate)GetValue(FullScreenLandscapeItemsPanelTemplateProperty); }
            set { SetValue(FullScreenLandscapeItemsPanelTemplateProperty, value); }
        }
        public static readonly DependencyProperty FullScreenLandscapeItemsPanelTemplateProperty =
            DependencyProperty.Register("FullScreenLandscapeItemsPanelTemplate", typeof(ItemsPanelTemplate), typeof(SuperListView), new PropertyMetadata(null));

        public ItemsPanelTemplate SnappedItemsPanelTemplate
        {
            get { return (ItemsPanelTemplate)GetValue(SnappedItemsPanelTemplateProperty); }
            set { SetValue(SnappedItemsPanelTemplateProperty, value); }
        }
        public static readonly DependencyProperty SnappedItemsPanelTemplateProperty =
            DependencyProperty.Register("SnappedItemsPanelTemplate", typeof(ItemsPanelTemplate), typeof(SuperListView), new PropertyMetadata(null));

        public ItemsPanelTemplate SnappedGroupedItemsPanelTemplate
        {
            get { return (ItemsPanelTemplate)GetValue(SnappedGroupedItemsPanelTemplateProperty); }
            set { SetValue(SnappedGroupedItemsPanelTemplateProperty, value); }
        }
        public static readonly DependencyProperty SnappedGroupedItemsPanelTemplateProperty =
            DependencyProperty.Register("SnappedGroupedItemsPanelTemplate", typeof(ItemsPanelTemplate), typeof(SuperListView), new PropertyMetadata(null));

        public string ItemsPath
        {
            get { return (string)GetValue(ItemsPathProperty); }
            set { SetValue(ItemsPathProperty, value); }
        }
        public static readonly DependencyProperty ItemsPathProperty =
            DependencyProperty.Register("ItemsPath", typeof(string), typeof(SuperListView), new PropertyMetadata(""));      

        public event PropertyChangedEventHandler PropertyChanged;
    }
}
